home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1998 January: Mac OS SDK / Dev.CD Jan 98 SDK1.toast / Development Kits (Disc 1) / Interfaces&Libraries / Universal / Interfaces / PInterfaces / PEFBinaryFormat.p < prev    next >
Encoding:
Text File  |  1997-08-12  |  37.6 KB  |  802 lines  |  [TEXT/MPS ]

  1. {
  2.      File:        PEFBinaryFormat.p
  3.  
  4.      Contains:    PEF Types and Macros
  5.  
  6.      Version:    Technology:    Master Interfaces
  7.                  Release:    Universal Interfaces 3.0.1
  8.  
  9.      Copyright:    © 1993-1997 by Apple Computer, Inc., all rights reserved.
  10.  
  11.      Bugs?:        Please include the the file and version information (from above) with
  12.                  the problem description.  Developers belonging to one of the Apple
  13.                  developer programs can submit bug reports to:
  14.  
  15.                      devsupport@apple.com
  16.  
  17. }
  18.  
  19.  
  20. {$IFC UNDEFINED UsingIncludes}
  21. {$SETC UsingIncludes := 0}
  22. {$ENDC}
  23.  
  24. {$IFC NOT UsingIncludes}
  25.  UNIT PEFBinaryFormat;
  26.  INTERFACE
  27. {$ENDC}
  28.  
  29. {$IFC UNDEFINED __PEFBINARYFORMAT__}
  30. {$SETC __PEFBINARYFORMAT__ := 1}
  31.  
  32. {$I+}
  33. {$SETC PEFBinaryFormatIncludes := UsingIncludes}
  34. {$SETC UsingIncludes := 1}
  35.  
  36. {$IFC UNDEFINED __TYPES__}
  37. {$I Types.p}
  38. {$ENDC}
  39.  
  40.  
  41. {$PUSH}
  42. {$ALIGN MAC68K}
  43. {$LibExport+}
  44.  
  45. { -----------------------------------------------------------------------------------------    }
  46. { Almost all types are padded for natural alignment.  However the PEFExportedSymbol type is    }
  47. { 10 bytes long, containing two 32 bit fields and one 16 bit field.  Arrays of it must be        }
  48. { packed, so it requires "68K" alignment.  Setting this globally to 68K should also help        }
  49. { ensure consistent treatment across compilers.                                                }
  50.  
  51. { ======================================================================================== }
  52. { Overall Structure }
  53. { ================= }
  54.  
  55. { -------------------------------------------------------------------------------------------    }
  56. { This header contains a complete set of types and macros for dealing with the PEF executable    }
  57. { format.  While some description is provided, this header is not meant as a primary source    }
  58. { of documentation on PEF.  An excellent specification of PEF can be found in the Macintosh    }
  59. { Runtime Architectures book.  This header is primarily a physical format description.  Thus    }
  60. { it depends on as few other headers as possible and structure fields have obvious sizes.        }
  61. {                                                                                                 }
  62. { The physical storage for a PEF executable is known as a "container".  This refers to just    }
  63. { the executable itself, not the file etc.  E.g. if five DLLs are packaged in a single file's    }
  64. { data fork, that one data fork has five containers within it.                                    }
  65. {                                                                                                 }
  66. { A PEF container consists of an overall header, followed by one or more section headers,        }
  67. { followed by the section name table, followed by the contents for the sections.  Some kinds    }
  68. { of sections have specific internal representation.  The "loader" section is the most common    }
  69. { of these special sections.  It contains information on the exports, imports, and runtime        }
  70. { relocations required to prepare the executable.  PEF containers are self contained, all        }
  71. { portions are located via relative offsets.                                                    }
  72. {                                                                                                 }
  73. {                                                                                                 }
  74. {            +-------------------------------+                                                    }
  75. {            |        Container Header        |    40 bytes                                        }
  76. {            +-------------------------------+                                                    }
  77. {            |        Section 0 header        |    28 bytes each                                    }
  78. {            |...............................|                                                    }
  79. {            |            - - - -                |                                                    }
  80. {            |...............................|                                                    }
  81. {            |        Section n-1 header        |                                                    }
  82. {            +-------------------------------+                                                    }
  83. {            |        Section Name Table        |                                                    }
  84. {            +-------------------------------+                                                    }
  85. {            |        Section x raw data        |                                                    }
  86. {            +-------------------------------+                                                    }
  87. {             |            - - - -                |                                                    }
  88. {            +-------------------------------+                                                    }
  89. {            |        Section y raw data        |                                                    }
  90. {            +-------------------------------+                                                    }
  91. {                                                                                                 }
  92. {                                                                                                 }
  93. { The sections are implicitly numbered from 0 to n according to the order of their headers.    }
  94. { The headers of the instantiated sections must precede those of the non-instantiated            }
  95. { sections.  The ordering of the raw data is independent of the section header ordering.        }
  96. { Each section header contains the offset for that section's raw data.                            }
  97.  
  98. { =========================================================================================== }
  99. { Container Header }
  100. { ================ }
  101.  
  102.  
  103. TYPE
  104.     PEFContainerHeaderPtr = ^PEFContainerHeader;
  105.     PEFContainerHeader = RECORD
  106.         tag1:                    OSType;                                    {  Must contain 'Joy!'.  }
  107.         tag2:                    OSType;                                    {  Must contain 'peff'.  (Yes, with two 'f's.)  }
  108.         architecture:            OSType;                                    {  The ISA for code sections.  Constants in CodeFragments.h.  }
  109.         formatVersion:            UInt32;                                    {  The physical format version.  }
  110.         dateTimeStamp:            UInt32;                                    {  Macintosh format creation/modification stamp.  }
  111.         oldDefVersion:            UInt32;                                    {  Old definition version number for the code fragment.  }
  112.         oldImpVersion:            UInt32;                                    {  Old implementation version number for the code fragment.  }
  113.         currentVersion:            UInt32;                                    {  Current version number for the code fragment.  }
  114.         sectionCount:            UInt16;                                    {  Total number of section headers that follow.  }
  115.         instSectionCount:        UInt16;                                    {  Number of instantiated sections.  }
  116.         reservedA:                UInt32;                                    {  Reserved, must be written as zero.  }
  117.     END;
  118.  
  119.  
  120. CONST
  121.     kPEFTag1                    = 'Joy!';                        {  For non-Apple compilers: 0x4A6F7921.  }
  122.     kPEFTag2                    = 'peff';                        {  For non-Apple compilers: 0x70656666.  }
  123.     kPEFVersion                    = $00000001;
  124.  
  125.  
  126.     kPEFFirstSectionHeaderOffset = 40;
  127.  
  128.  
  129. { =========================================================================================== }
  130. { Section Headers }
  131. { =============== }
  132.  
  133.  
  134. TYPE
  135.     PEFSectionHeaderPtr = ^PEFSectionHeader;
  136.     PEFSectionHeader = RECORD
  137.         nameOffset:                SInt32;                                    {  Offset of name within the section name table, -1 => none.  }
  138.         defaultAddress:            UInt32;                                    {  Default address, affects relocations.  }
  139.         totalLength:            UInt32;                                    {  Fully expanded size in bytes of the section contents.  }
  140.         unpackedLength:            UInt32;                                    {  Size in bytes of the "initialized" part of the contents.  }
  141.         containerLength:        UInt32;                                    {  Size in bytes of the raw data in the container.  }
  142.         containerOffset:        UInt32;                                    {  Offset of section's raw data.  }
  143.         sectionKind:            SInt8;                                    {  Kind of section contents/usage.  }
  144.         shareKind:                SInt8;                                    {  Sharing level, if a writeable section.  }
  145.         alignment:                SInt8;                                    {  Preferred alignment, expressed as log 2.  }
  146.         reservedA:                SInt8;                                    {  Reserved, must be zero.  }
  147.     END;
  148.  
  149.  
  150. CONST
  151.                                                                 {  Values for the sectionKind field.  }
  152.                                                                 {     Section kind values for instantiated sections.  }
  153.     kPEFCodeSection                = 0;                            {  Code, presumed pure & position independent.  }
  154.     kPEFUnpackedDataSection        = 1;                            {  Unpacked writeable data.  }
  155.     kPEFPackedDataSection        = 2;                            {  Packed writeable data.  }
  156.     kPEFConstantSection            = 3;                            {  Read-only data.  }
  157.     kPEFExecDataSection            = 6;                            {  Intermixed code and writeable data.  }
  158.                                                                 {  Section kind values for non-instantiated sections.  }
  159.     kPEFLoaderSection            = 4;                            {  Loader tables.  }
  160.     kPEFDebugSection            = 5;                            {  Reserved for future use.  }
  161.     kPEFExceptionSection        = 7;                            {  Reserved for future use.  }
  162.     kPEFTracebackSection        = 8;                            {  Reserved for future use.  }
  163.  
  164.  
  165.                                                                 {  Values for the shareKind field.  }
  166.     kPEFProcessShare            = 1;                            {  Shared within a single process.  }
  167.     kPEFGlobalShare                = 4;                            {  Shared across the entire system.  }
  168.     kPEFProtectedShare            = 5;                            {  Readable across the entire system, writeable only to privileged code.  }
  169.  
  170.  
  171. { =========================================================================================== }
  172. { Packed Data Contents }
  173. { ==================== }
  174.  
  175. { -------------------------------------------------------------------------------------------    }
  176. { The raw contents of a packed data section are a sequence of byte codes.  The basic format    }
  177. { has a 3 bit opcode followed by a 5 bit count.  Additional bytes might be used to contain        }
  178. { counts larger than 31, and to contain a second or third count.  Further additional bytes        }
  179. { contain actual data values to transfer.                                                        }
  180. {                                                                                                 }
  181. { All counts are represented in a variable length manner.  A zero in the initial 5 bit count    }
  182. { indicates the actual value follows.  In this case, and for the second and third counts, the    }
  183. { count is represented as a variable length sequence of bytes.  The bytes are stored in big    }
  184. { endian manner, most significant part first.  The high order bit is set in all but the last    }
  185. { byte.  The value is accumulated by shifting the current value up 7 bits and adding in the    }
  186. { low order 7 bits of the next byte.                                                            }
  187.  
  188.                                                                 {  The packed data opcodes.  }
  189.     kPEFPkDataZero                = 0;                            {  Zero fill "count" bytes.  }
  190.     kPEFPkDataBlock                = 1;                            {  Block copy "count" bytes.  }
  191.     kPEFPkDataRepeat            = 2;                            {  Repeat "count" bytes "count2"+1 times.  }
  192.     kPEFPkDataRepeatBlock        = 3;                            {  Interleaved repeated and unique data.  }
  193.     kPEFPkDataRepeatZero        = 4;                            {  Interleaved zero and unique data.  }
  194.  
  195.  
  196.     kPEFPkDataOpcodeShift        = 5;
  197.     kPEFPkDataCount5Mask        = $1F;
  198.     kPEFPkDataMaxCount5            = 31;
  199.     kPEFPkDataVCountShift        = 7;
  200.     kPEFPkDataVCountMask        = $7F;
  201.     kPEFPkDataVCountEndMask        = $80;
  202.  
  203.  
  204.  
  205. { ------------------------------------------------------------------------------------------    }
  206. { The following code snippet can be used to input a variable length count.                        }
  207. {                                                                                                 }
  208. {        count = 0;                                                                                }
  209. {        do (                                                                                    }
  210. {            byte = *bytePtr++;                                                                    }
  211. {            count = (count << kPEFPkDataVCountShift) | (byte & kPEFPkDataVCountMask);            }
  212. {        ) while ( (byte & kPEFPkDataVCountEndMask) != 0 );                                        }
  213. {                                                                                                 }
  214. { The following code snippet can be used to output a variable length count to a byte array.    }
  215. { This is more complex than the input code because the chunks are output in big endian order.    }
  216. { Think about handling values like 0 or 0x030000.                                                }
  217. {                                                                                                 }
  218. {        count = 1;.                                                                                }
  219. {        tempValue = value >> kPEFPkDataCountShift;                                                }
  220. {        while ( tempValue != 0 ) (                                                                }
  221. {            count += 1;                                                                            }
  222. {            tempValue = tempValue >> kPEFPkDataCountShift;                                        }
  223. {        )                                                                                        }
  224. {                                                                                                 }
  225. {        bytePtr += count;                                                                        }
  226. {        tempPtr = bytePtr - 1;                                                                    }
  227. {        *tempPtr-- = value;        // ! No need to mask, only the low order byte is stored.        }
  228. {        for ( count -= 1; count != 0; count -= 1 ) (                                            }
  229. {            value = value >> kPEFPkDataCountShift;                                                }
  230. {            *tempPtr-- = value | kPEFPkDataCountEndMask;                                        }
  231. {        )                                                                                        }
  232.  
  233. { =========================================================================================== }
  234. { Loader Section }
  235. { ============== }
  236.  
  237. { ------------------------------------------------------------------------------------------    }
  238. { The loader section contains information needed to prepare the code fragment for execution.    }
  239. { This includes this fragment's exports, the import libraries and the imported symbols from    }
  240. { each library, and the relocations for the writeable sections.                                }
  241. {                                                                                                 }
  242. {            +-----------------------------------+                <-- containerOffset --------+    }
  243. {            |        Loader Info Header            |    56 bytes                                |    }
  244. {            |-----------------------------------|                                            |    }
  245. {            |        Imported Library 0            |    24 bytes each                            |    }
  246. {            |...................................|                                            |    }
  247. {            |            - - -                    |                                            |    }
  248. {            |...................................|                                            |    }
  249. {            |        Imported Library l-1        |                                            |    }
  250. {            |-----------------------------------|                                            |    }
  251. {            |        Imported Symbol 0            |    4 bytes each                            |    }
  252. {            |...................................|                                            |    }
  253. {            |            - - -                    |                                            |    }
  254. {            |...................................|                                            |    }
  255. {            |         Imported Symbol i-1            |                                            |    }
  256. {            |-----------------------------------|                                            |    }
  257. {            |        Relocation Header 0            |    12 bytes each                            |    }
  258. {            |...................................|                                            |    }
  259. {            |            - - -                    |                                            |    }
  260. {            |...................................|                                            |    }
  261. {            |        Relocation Header r-1        |                                            |    }
  262. {            |-----------------------------------|                <-- + relocInstrOffset -----|    }
  263. {            |        Relocation Instructions        |                                            |    }
  264. {            |-----------------------------------|                <-- + loaderStringsOffset --|    }
  265. {            |        Loader String Table            |                                            |    }
  266. {            |-----------------------------------|                <-- + exportHashOffset -----+    }
  267. {            |        Export Hash Slot 0            |    4 bytes each                                }
  268. {            |...................................|                                                }
  269. {            |            - - -                    |                                                }
  270. {            |...................................|                                                }
  271. {            |         Export Hash Slot h-1        |                                                }
  272. {            |-----------------------------------|                                                }
  273. {            |        Export Symbol Key 0            |    4 bytes each                                }
  274. {            |...................................|                                                }
  275. {            |            - - -                    |                                                }
  276. {            |...................................|                                                }
  277. {            |        Export Symbol Key e-1        |                                                }
  278. {            |-----------------------------------|                                                }
  279. {            |        Export Symbol 0                |    10 bytes each                                }
  280. {            |...................................|                                                }
  281. {            |            - - -                    |                                                }
  282. {            |...................................|                                                }
  283. {            |        Export Symbol e-1            |                                                }
  284. {            +-----------------------------------+                                                }
  285.  
  286.  
  287. TYPE
  288.     PEFLoaderInfoHeaderPtr = ^PEFLoaderInfoHeader;
  289.     PEFLoaderInfoHeader = RECORD
  290.         mainSection:            SInt32;                                    {  Section containing the main symbol, -1 => none.  }
  291.         mainOffset:                UInt32;                                    {  Offset of main symbol.  }
  292.         initSection:            SInt32;                                    {  Section containing the init routine's TVector, -1 => none.  }
  293.         initOffset:                UInt32;                                    {  Offset of the init routine's TVector.  }
  294.         termSection:            SInt32;                                    {  Section containing the term routine's TVector, -1 => none.  }
  295.         termOffset:                UInt32;                                    {  Offset of the term routine's TVector.  }
  296.         importedLibraryCount:    UInt32;                                    {  Number of imported libraries.  ('l')  }
  297.         totalImportedSymbolCount: UInt32;                                {  Total number of imported symbols.  ('i')  }
  298.         relocSectionCount:        UInt32;                                    {  Number of sections with relocations.  ('r')  }
  299.         relocInstrOffset:        UInt32;                                    {  Offset of the relocation instructions.  }
  300.         loaderStringsOffset:    UInt32;                                    {  Offset of the loader string table.  }
  301.         exportHashOffset:        UInt32;                                    {  Offset of the export hash table.  }
  302.         exportHashTablePower:    UInt32;                                    {  Export hash table size as log 2.  (Log2('h'))  }
  303.         exportedSymbolCount:    UInt32;                                    {  Number of exported symbols.  ('e')  }
  304.     END;
  305.  
  306. { =========================================================================================== }
  307. { Imported Libraries }
  308. { ------------------ }
  309.     PEFImportedLibraryPtr = ^PEFImportedLibrary;
  310.     PEFImportedLibrary = RECORD
  311.         nameOffset:                UInt32;                                    {  Loader string table offset of library's name.  }
  312.         oldImpVersion:            UInt32;                                    {  Oldest compatible implementation version.  }
  313.         currentVersion:            UInt32;                                    {  Current version at build time.  }
  314.         importedSymbolCount:    UInt32;                                    {  Imported symbol count for this library.  }
  315.         firstImportedSymbol:    UInt32;                                    {  Index of first imported symbol from this library.  }
  316.         options:                SInt8;                                    {  Option bits for this library.  }
  317.         reservedA:                SInt8;                                    {  Reserved, must be zero.  }
  318.         reservedB:                UInt16;                                    {  Reserved, must be zero.  }
  319.     END;
  320.  
  321.  
  322. CONST
  323.                                                                 {  Bits for the PEFImportedLibrary options field.  }
  324.     kPEFWeakImportLibMask        = $40;                            {  The imported library is allowed to be missing.  }
  325.     kPEFInitLibBeforeMask        = $80;                            {  The imported library must be initialized first.  }
  326.  
  327.  
  328. { =========================================================================================== }
  329. { Imported Symbols }
  330. { ---------------- }
  331.  
  332. { -------------------------------------------------------------------------------------------    }
  333. { The PEFImportedSymbol type has the following bit field layout.                                }
  334. {                                                                                                 }
  335. {                                                                       3                        }
  336. {         0             7 8                                             1                        }
  337. {        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                        }
  338. {      | symbol class  | offset of symbol name in loader string table  |                        }
  339. {        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                        }
  340. {        |<-- 8 bits --->|<-- 24 bits ---------------------------------->|                        }
  341.  
  342.  
  343. TYPE
  344.     PEFImportedSymbolPtr = ^PEFImportedSymbol;
  345.     PEFImportedSymbol = RECORD
  346.         classAndName:            UInt32;
  347.     END;
  348.  
  349.  
  350. CONST
  351.     kPEFImpSymClassShift        = 24;
  352.     kPEFImpSymNameOffsetMask    = $00FFFFFF;
  353.     kPEFImpSymMaxNameOffset        = $00FFFFFF;                    {  16,777,215  }
  354.  
  355.  
  356.                                                                 {  Imported and exported symbol classes.  }
  357.     kPEFCodeSymbol                = $00;
  358.     kPEFDataSymbol                = $01;
  359.     kPEFTVectorSymbol            = $02;
  360.     kPEFTOCSymbol                = $03;
  361.     kPEFGlueSymbol                = $04;
  362.     kPEFUndefinedSymbol            = $0F;
  363.     kPEFWeakImportSymMask        = $80;
  364.  
  365.  
  366. { =========================================================================================== }
  367. { Exported Symbol Hash Table }
  368. { -------------------------- }
  369.  
  370. { -------------------------------------------------------------------------------------------    }
  371. { Exported symbols are described in four parts, optimized for speed of lookup.  These parts    }
  372. { are the "export hash table", the "export key table", the "export symbol table", and the        }
  373. { "export name table".  Overall they contain a flattened representation of a fairly normal        }
  374. { hashed symbol table.                                                                            }
  375. {                                                                                                }
  376. { The export hash table is an array of small fixed size elements.  The number of elements is    }
  377. { a power of 2.  A 32 bit hash word for a symbol is converted into an index into this array.    }
  378. { Each hash slot contains a count of the number of exported symbols that map to this slot and    }
  379. { the index of the first of those symbols in the key and symbol tables.  Of course some hash    }
  380. { slots will have a zero count.                                                                }
  381. {                                                                                                }
  382. { The key and symbol tables are also arrays of fixed size elements, one for each exported        }
  383. { symbol.  Their entries are grouped by hash slot, those elements mapping to the same hash        }
  384. { slot are contiguous.  The key table contains just the full 32 bit hash word for each            }
  385. { exported symbol.  The symbol table contains the offset of the symbol's name in the string    }
  386. { table and other information about the exported symbol.                                        }
  387. {                                                                                                }
  388. { To look up an export you take the hashword and compute the hash slot index.  You then scan    }
  389. { the indicated portion of the key table for matching hashwords.  If a hashword matches, you    }
  390. { look at the corresponding symbol table entry to find the full symbol name.  If the names        }
  391. { match the symbol is found.                                                                    }
  392.  
  393. { -------------------------------------------------------------------------------------------    }
  394. { The following function may be used to compute the hash table size.  Signed values are used    }
  395. { just to avoid potential code generation overhead for unsigned division.                        }
  396. {                                                                                                 }
  397. {        UInt8    PEFComputeHashTableExponent    ( SInt32    exportCount )                            }
  398. {        (                                                                                        }
  399. {            SInt32    exponent;                                                                    }
  400. {                                                                                                 }
  401. {            const SInt32    kExponentLimit        = 16;    // Arbitrary, but must not exceed 30.    }
  402. {            const SInt32    kAverageChainLimit    = 10;    // Arbitrary, for space/time tradeoff.    }
  403. {                                                                                                 }
  404. {            for ( exponent = 0; exponent < kExponentLimit; exponent += 1 ) (                    }
  405. {                if ( (exportCount / (1 << exponent)) < kAverageChainLimit ) break;                }
  406. {            )                                                                                    }
  407. {                                                                                                 }
  408. {            return exponent;                                                                    }
  409. {                                                                                                 }
  410. {        )    // PEFComputeHashTableExponent ()                                                    }
  411.  
  412. { -------------------------------------------------------------------------------------------    }
  413. { The PEFExportedSymbolHashSlot type has the following bit field layout.                        }
  414. {                                                                                                 }
  415. {                                   1 1                                 3                        }
  416. {         0                         3 4                                 1                        }
  417. {        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                        }
  418. {        | symbol count              | index of first export key         |                        }
  419. {        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                        }
  420. {        |<-- 14 bits -------------->|<-- 18 bits ---------------------->|                        }
  421.  
  422.  
  423. TYPE
  424.     PEFExportedSymbolHashSlotPtr = ^PEFExportedSymbolHashSlot;
  425.     PEFExportedSymbolHashSlot = RECORD
  426.         countAndStart:            UInt32;
  427.     END;
  428.  
  429.  
  430. CONST
  431.     kPEFHashSlotSymCountShift    = 18;
  432.     kPEFHashSlotFirstKeyMask    = $0003FFFF;
  433.     kPEFHashSlotMaxSymbolCount    = $00003FFF;                    {   16,383  }
  434.     kPEFHashSlotMaxKeyIndex        = $0003FFFF;                    {  262,143  }
  435.  
  436.  
  437. { =========================================================================================== }
  438. { Exported Symbol Hash Key }
  439. { ------------------------ }
  440.  
  441.  
  442. TYPE
  443.     PEFSplitHashWordPtr = ^PEFSplitHashWord;
  444.     PEFSplitHashWord = RECORD
  445.         nameLength:                UInt16;
  446.         hashValue:                UInt16;
  447.     END;
  448.  
  449.     PEFExportedSymbolKeyPtr = ^PEFExportedSymbolKey;
  450.     PEFExportedSymbolKey = RECORD
  451.         CASE INTEGER OF
  452.         0: (
  453.             fullHashWord:        UInt32;
  454.             );
  455.         1: (
  456.             splitHashWord:        PEFSplitHashWord;
  457.             );
  458.     END;
  459.  
  460.  
  461. CONST
  462.     kPEFHashLengthShift            = 16;
  463.     kPEFHashValueMask            = $0000FFFF;
  464.     kPEFHashMaxLength            = $0000FFFF;                    {  65,535  }
  465.  
  466.  
  467. { -------------------------------------------------------------------------------------------            }
  468. { The following function computes the full 32 bit hash word.                                            }
  469. {                                                                                                         }
  470. {        UInt32    PEFComputeHashWord    ( BytePtr    nameText,        // ! First "letter", not length byte.    }
  471. {                                      UInt32    nameLength )    // ! The text may be zero terminated.    }
  472. {        (                                                                                                }
  473. {            BytePtr    charPtr        = nameText;                                                                }
  474. {            SInt32    hashValue    = 0;        // ! Signed to match old published algorithm.                }
  475. {            UInt32    length        = 0;                                                                    }
  476. {            UInt32    limit;                                                                                }
  477. {            UInt32    result;                                                                                }
  478. {            UInt8    currChar;                                                                            }
  479. {                                                                                                         }
  480. {            #define PseudoRotate(x)  ( ( (x) << 1 ) - ( (x) >> 16 ) )                                    }
  481. {                                                                                                         }
  482. {            for ( limit = nameLength; limit > 0; limit -= 1 ) (                                            }
  483. {                currChar = *charPtr++;                                                                    }
  484. {                if ( currChar == NULL ) break;                                                            }
  485. {                length += 1;                                                                            }
  486. {                hashValue = PseudoRotate ( hashValue ) ^ currChar;                                        }
  487. {            )                                                                                            }
  488. {                                                                                                         }
  489. {            result    = (length << kPEFHashLengthShift) |                                                    }
  490. {                      ((UInt16) ((hashValue ^ (hashValue >> 16)) & kPEFHashValueMask));                    }
  491. {                                                                                                         }
  492. {            return result;                                                                                }
  493. {                                                                                                         }
  494. {        )    // PEFComputeHashWord ()                                                                    }
  495.  
  496. { =========================================================================================== }
  497. { Exported Symbols }
  498. { ---------------- }
  499.  
  500.  
  501. TYPE
  502.     PEFExportedSymbolPtr = ^PEFExportedSymbol;
  503.     PEFExportedSymbol = RECORD
  504.                                                                         {  ! This structure is 10 bytes long and arrays are packed.  }
  505.         classAndName:            UInt32;                                    {  A combination of class and name offset.  }
  506.         symbolValue:            UInt32;                                    {  Typically the symbol's offset within a section.  }
  507.         sectionIndex:            SInt16;                                    {  The index of the section, or pseudo-section, for the symbol.  }
  508.     END;
  509.  
  510. { -------------------------------------------------------------------------------------------    }
  511. { The classAndName field of the PEFExportedSymbol type has the following bit field layout.        }
  512. {                                                                                                 }
  513. {                                                                       3                        }
  514. {         0             7 8                                             1                        }
  515. {        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                        }
  516. {      | symbol class  | offset of symbol name in loader string table  |                        }
  517. {        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                        }
  518. {        |<-- 8 bits --->|<-- 24 bits ---------------------------------->|                        }
  519.  
  520.  
  521. CONST
  522.     kPEFExpSymClassShift        = 24;
  523.     kPEFExpSymNameOffsetMask    = $00FFFFFF;
  524.     kPEFExpSymMaxNameOffset        = $00FFFFFF;                    {  16,777,215  }
  525.  
  526.  
  527.                                                                 {  Negative section indices indicate pseudo-sections.  }
  528.     kPEFAbsoluteExport            = -2;                            {  The symbol value is an absolute address.  }
  529.     kPEFReexportedImport        = -3;                            {  The symbol value is the index of a reexported import.  }
  530.  
  531.  
  532. { =========================================================================================== }
  533. { Loader Relocations }
  534. { ================== }
  535.  
  536. { -------------------------------------------------------------------------------------------    }
  537. { The relocations for a section are defined by a sequence of instructions for an abstract        }
  538. { machine that is specifically geared to performing relocations commonly needed for the "CFM"    }
  539. { code generation model.  These instructions occur in 16 bit chunks.  Most instructions have    }
  540. { just a single chunk.  Instructions that are larger than 16 bits have an opcode and some of    }
  541. { the operands in the first chunk, with other operands in following chunks.                    }
  542.  
  543.  
  544. TYPE
  545.     PEFRelocChunk                        = UInt16;
  546.     PEFLoaderRelocationHeaderPtr = ^PEFLoaderRelocationHeader;
  547.     PEFLoaderRelocationHeader = RECORD
  548.         sectionIndex:            UInt16;                                    {  Index of the section to be fixed up.  }
  549.         reservedA:                UInt16;                                    {  Reserved, must be zero.  }
  550.         relocCount:                UInt32;                                    {  Number of 16 bit relocation chunks.  }
  551.         firstRelocOffset:        UInt32;                                    {  Offset of first relocation instruction.  }
  552.     END;
  553.  
  554. { -------------------------------------------------------------------------------------------    }
  555. { ! Note that the relocCount field is the number of 16 bit relocation chunks, i.e. 1/2 the        }
  556. { ! total number of bytes of relocation instructions.  While most relocation instructions are    }
  557. { ! 16 bits long, some are longer so the number of complete relocation instructions may be        }
  558. { ! less than the relocCount value.                                                            }
  559.  
  560. { ----------------------------------------------------------------------------------    }
  561. { The PEFRelocField macro is a utility for extracting relocation instruction fields.    }
  562.  
  563. { =========================================================================================== }
  564. { Basic Relocation Opcodes }
  565. { ------------------------ }
  566. { ------------------------------------------------------------------------------------------    }
  567. { The number of opcode bits varies from 2 to 7.  The enumeration and switch table given here    }
  568. { are defined in terms of the most significant 7 bits of the first instruction chunk.  An        }
  569. { instruction is decoded by using the most significant 7 bits as an index into the opcode        }
  570. { table, which in turn contains appropriately masked forms of the most significant 7 bits.        }
  571. { The macro PEFRelocBasicOpcode assumes a declaration of the form.                                }
  572. {                                                                                                 }
  573. {        UInt8 kPEFRelocBasicOpcodes [kPEFRelocBasicOpcodeRange] = ( PEFMaskedBasicOpcodes );    }
  574.  
  575.  
  576. CONST
  577.     kPEFRelocBasicOpcodeRange    = 128;
  578.  
  579.  
  580. { -------------------------------------------------------------------------------------------    }
  581. { The relocation opcodes, clustered by major and minor groups.  The instructions within a        }
  582. { cluster all have the same bit field layout.  The enumeration values use the high order 7        }
  583. { bits of the relocation instruction.  Unused low order bits are set to zero.                    }
  584.     kPEFRelocBySectDWithSkip    = $00;                            {  Binary: 00x_xxxx  }
  585.     kPEFRelocBySectC            = $20;                            {  Binary: 010_0000, group is "RelocRun"  }
  586.     kPEFRelocBySectD            = $21;                            {  Binary: 010_0001  }
  587.     kPEFRelocTVector12            = $22;                            {  Binary: 010_0010  }
  588.     kPEFRelocTVector8            = $23;                            {  Binary: 010_0011  }
  589.     kPEFRelocVTable8            = $24;                            {  Binary: 010_0100  }
  590.     kPEFRelocImportRun            = $25;                            {  Binary: 010_0101  }
  591.     kPEFRelocSmByImport            = $30;                            {  Binary: 011_0000, group is "RelocSmIndex"  }
  592.     kPEFRelocSmSetSectC            = $31;                            {  Binary: 011_0001  }
  593.     kPEFRelocSmSetSectD            = $32;                            {  Binary: 011_0010  }
  594.     kPEFRelocSmBySection        = $33;                            {  Binary: 011_0011  }
  595.     kPEFRelocIncrPosition        = $40;                            {  Binary: 100_0xxx  }
  596.     kPEFRelocSmRepeat            = $48;                            {  Binary: 100_1xxx  }
  597.     kPEFRelocSetPosition        = $50;                            {  Binary: 101_000x  }
  598.     kPEFRelocLgByImport            = $52;                            {  Binary: 101_001x  }
  599.     kPEFRelocLgRepeat            = $58;                            {  Binary: 101_100x  }
  600.     kPEFRelocLgSetOrBySection    = $5A;                            {  Binary: 101_101x  }
  601.     kPEFRelocUndefinedOpcode    = $FF;                            {  Used in masking table for all undefined values.  }
  602.  
  603.  
  604. { ----------------------------------------------------------------------------    }
  605. { The RelocLgSetOrBySection instruction has an additional 4 bits of subopcode.    }
  606.     kPEFRelocLgBySectionSubopcode = $00;                        {  Binary: 0000  }
  607.     kPEFRelocLgSetSectCSubopcode = $01;                            {  Binary: 0001  }
  608.     kPEFRelocLgSetSectDSubopcode = $02;                            {  Binary: 0010  }
  609.  
  610.  
  611. { ------------------------------------------------------------------------------------------    }
  612. { The initial values for the opcode "masking" table.  This has the enumeration values from        }
  613. { above with appropriate replications for "don't care" bits.  It is almost certainly shorter    }
  614. { and faster to look up the masked value in a table than to use a branch tree.                    }
  615.  
  616. { =========================================================================================== }
  617. { RelocBySectDWithSkip Instruction }
  618. { -------------------------------- }
  619.  
  620. { -------------------------------------------------------------------------------------------    }
  621. { The "RelocBySectDWithSkip" instruction has the following bit field layout.                    }
  622. {                                                                                                 }
  623. {                             1         1                                                        }
  624. {         0 1 2             9 0         5                                                        }
  625. {        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                                                        }
  626. {        |0 0| skip count    | rel count |                                                        }
  627. {        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                                                        }
  628. {        | 2 |<-- 8 bits --->|<--  6 --->|                                                        }
  629. {                                                                                                 }
  630. { ! Note that the stored skip count and reloc count are the actual values!                        }
  631.     kPEFRelocWithSkipMaxSkipCount = 255;
  632.     kPEFRelocWithSkipMaxRelocCount = 63;
  633.  
  634.  
  635. { =========================================================================================== }
  636. { RelocRun Group }
  637. { -------------- }
  638.  
  639. { -------------------------------------------------------------------------------------------    }
  640. { The "RelocRun" group includes the "RelocBySectC", "RelocBySectD", "RelocTVector12",            }
  641. { "RelocTVector8", "RelocVTable8", and "RelocImportRun" instructions.  This group has the        }
  642. { following bit field layout.                                                                    }
  643. {                                                                                                 }
  644. {                                       1                                                        }
  645. {         0   2 3     6 7               5                                                        }
  646. {        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                                                        }
  647. {        |0 1 0| subop.| run length      |                                                        }
  648. {        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                                                        }
  649. {        |  3  |<- 4 ->|<-- 9 bits ----->|                                                        }
  650. {                                                                                                 }
  651. { ! Note that the stored run length is the actual value minus 1, but the macros deal with the    }
  652. { ! actual value!                                                                                }
  653.     kPEFRelocRunMaxRunLength    = 512;
  654.  
  655.  
  656. { =========================================================================================== }
  657. { RelocSmIndex Group }
  658. { ------------------ }
  659.  
  660. { ----------------------------------------------------------------------------------------    }
  661. { The "RelocSmIndex" group includes the "RelocSmByImport", "RelocSmSetSectC",                }
  662. { "RelocSmSetSectD" and "RelocSmBySection" instructions.  This group has the following bit    }
  663. { field layout.                                                                            }
  664. {                                                                                             }
  665. {                                       1                                                    }
  666. {         0   2 3     6 7               5                                                    }
  667. {        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                                                    }
  668. {        |0 1 1| subop.| index           |                                                    }
  669. {        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                                                    }
  670. {        |  3  |<- 4 ->|<-- 9 bits ----->|                                                    }
  671. {                                                                                             }
  672. { ! Note that the stored index is the actual value!                                        }
  673.     kPEFRelocSmIndexMaxIndex    = 511;
  674.  
  675.  
  676. { =========================================================================================== }
  677. { RelocIncrPosition Instruction }
  678. { ----------------------------- }
  679.  
  680. { -------------------------------------------------------------------------------------------    }
  681. { The "RelocIncrPosition" instruction has the following bit field layout.                        }
  682. {                                                                                                 }
  683. {                                       1                                                        }
  684. {         0     3 4                     5                                                        }
  685. {        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                                                        }
  686. {        |1 0 0 0| offset                |                                                        }
  687. {        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                                                        }
  688. {        |<- 4 ->|<-- 12 bits ---------->|                                                        }
  689. {                                                                                                 }
  690. { ! Note that the stored offset is the actual value minus 1, but the macros deal with the        }
  691. { ! actual value!                                                                                }
  692.     kPEFRelocIncrPositionMaxOffset = 4096;
  693.  
  694.  
  695. { =========================================================================================== }
  696. { RelocSmRepeat Instruction }
  697. { ------------------------- }
  698.  
  699. { -------------------------------------------------------------------------------------------    }
  700. { The "RelocSmRepeat" instruction has the following bit field layout.                            }
  701. {                                                                                                 }
  702. {                                       1                                                        }
  703. {         0     3 4     7 8             5                                                        }
  704. {        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                                                        }
  705. {        |1 0 0 1| chnks | repeat count  |                                                        }
  706. {        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                                                        }
  707. {        |<- 4 ->|<- 4 ->|<-- 8 bits --->|                                                        }
  708. {                                                                                                 }
  709. { ! Note that the stored chunk count and repeat count are the actual values minus 1, but the    }
  710. { ! macros deal with the actual values!                                                        }
  711.     kPEFRelocSmRepeatMaxChunkCount = 16;
  712.     kPEFRelocSmRepeatMaxRepeatCount = 256;
  713.  
  714.  
  715. { =========================================================================================== }
  716. { RelocSetPosition Instruction }
  717. { ---------------------------- }
  718.  
  719. { -------------------------------------------------------------------------------------------    }
  720. { The "RelocSetPosition" instruction has the following bit field layout.                        }
  721. {                                                                                                 }
  722. {                                       1                                   1                    }
  723. {         0         5 6                 5     0                             5                    }
  724. {        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                    }
  725. {        |1 0 1 0 0 0| offset (high)     |   | offset (low)                  |                    }
  726. {        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                    }
  727. {        |<-- 6 ---->|<-- 10 bits ------>|   |<-- 16 bits ------------------>|                    }
  728. {                                                                                                 }
  729. { ! Note that the stored offset is the actual value!                                            }
  730.     kPEFRelocSetPosMaxOffset    = $03FFFFFF;                    {  67,108,863  }
  731.  
  732.  
  733. { =========================================================================================== }
  734. { RelocLgByImport Instruction }
  735. { --------------------------- }
  736.  
  737. { -------------------------------------------------------------------------------------------    }
  738. { The "RelocLgByImport" instruction has the following bit field layout.                        }
  739. {                                                                                                 }
  740. {                                       1                                   1                    }
  741. {         0         5 6                 5     0                             5                    }
  742. {        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                    }
  743. {        |1 0 1 0 0 1| index (high)      |   | index (low)                   |                    }
  744. {        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                    }
  745. {        |<-- 6 ---->|<-- 10 bits ------>|   |<-- 16 bits ------------------>|                    }
  746. {                                                                                                 }
  747. { ! Note that the stored offset is the actual value!                                            }
  748.     kPEFRelocLgByImportMaxIndex    = $03FFFFFF;                    {  67,108,863  }
  749.  
  750.  
  751. { =========================================================================================== }
  752. { RelocLgRepeat Instruction }
  753. { ------------------------- }
  754.  
  755. { -------------------------------------------------------------------------------------------    }
  756. { The "RelocLgRepeat" instruction has the following bit field layout.                            }
  757. {                                                                                                 }
  758. {                             1         1                                   1                    }
  759. {         0         5 6     9 0         5     0                             5                    }
  760. {        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                    }
  761. {        |1 0 1 1 0 0| chnks | rpt (high)|   | repeat count (low)            |                    }
  762. {        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                    }
  763. {        |<--  6 --->|<- 4 ->|<--  6 --->|   |<-- 16 bits ------------------>|                    }
  764. {                                                                                                 }
  765. { ! Note that the stored chunk count is the actual value minus 1, but the macros deal with        }
  766. { ! the actual value!  The stored repeat count is the actual value!                            }
  767.     kPEFRelocLgRepeatMaxChunkCount = 16;
  768.     kPEFRelocLgRepeatMaxRepeatCount = $003FFFFF;                {  4,194,303  }
  769.  
  770.  
  771. { =========================================================================================== }
  772. { RelocLgSetOrBySection Group }
  773. { --------------------------- }
  774.  
  775. { -------------------------------------------------------------------------------------------    }
  776. { The "RelocLgSetOrBySection" instruction is really a group including the "RelocLgBySection",    }
  777. { "RelocLgSetSectC" and "RelocLgSetSectD" instructions.  This group has the following bit        }
  778. { field layout.                                                                                }
  779. {                                                                                                 }
  780. {                             1         1                                   1                    }
  781. {         0         5 6     9 0         5     0                             5                    }
  782. {        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                    }
  783. {        |1 0 1 1 0 1| subop | idx (high)|   | index (low)                   |                    }
  784. {        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                    }
  785. {        |<--  6 --->|<- 4 ->|<--  6 --->|   |<-- 16 bits ------------------>|                    }
  786. {                                                                                                 }
  787. { ! Note that the stored index is the actual value!                                            }
  788.     kPEFRelocLgSetOrBySectionMaxIndex = $003FFFFF;                {  4,194,303  }
  789.  
  790.  
  791.  
  792. {$ALIGN RESET}
  793. {$POP}
  794.  
  795. {$SETC UsingIncludes := PEFBinaryFormatIncludes}
  796.  
  797. {$ENDC} {__PEFBINARYFORMAT__}
  798.  
  799. {$IFC NOT UsingIncludes}
  800.  END.
  801. {$ENDC}
  802.